package com.yxq.mdt.app.net;

import android.accounts.NetworkErrorException;
import android.content.Context;

import com.alibaba.android.arouter.launcher.ARouter;
import com.alibaba.fastjson.JSON;
import com.blankj.utilcode.util.ToastUtils;
import com.hyphenate.chat.EMClient;
import com.orhanobut.hawk.Hawk;
import com.yxq.mdt.app.application.App;
import com.yxq.mdt.app.base.RespBase;
import com.yxq.mdt.app.constant.RouteTable;
import com.yxq.mdt.app.constant.SPKey;

import java.lang.reflect.ParameterizedType;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;

import io.reactivex.Observer;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;
import retrofit2.HttpException;


/**
 * @描述 网络请求基类-观察者
 * @作者 yd
 * @创建日期 2019/8/27 0027 15:07
 */
public abstract class BaseObserver<T> implements Observer<T> {

    protected Context mContext;

    public Class<T> getTClass() {
        Class<T> tClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return tClass;
    }

    public BaseObserver(Context mContext) {
        this.mContext = mContext;
    }

    public BaseObserver() {
    }

    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
        /**
         * 数据请求开始
         */
    }

    @Override
    public void onNext(@NonNull T tBaseEntity) {
        try {
            if (tBaseEntity instanceof RespBase) {
                //判断登录Token过期 跳转到登录页面
                RespBase respBase = (RespBase) tBaseEntity;
                if ((respBase.getCode() == -1 && respBase.getMsg().contains("登录")) || (respBase.getCode() == 400 && respBase.getMsg().contains("未登录"))) {
                    logOut();
                }
            }
            onSuccess(tBaseEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onError(@NonNull Throwable e) {
        try {
            if (e instanceof ConnectException
                    || e instanceof TimeoutException
                    || e instanceof NetworkErrorException
                    || e instanceof UnknownHostException) {
                onFailure(e, true);
            } else if (e instanceof HttpException) {
                HttpException httpException = (HttpException) e;
                ResponseBody responseBody = httpException.response().errorBody();
                if (responseBody != null) {
                    String json = responseBody.string();
                    onCodeError(JSON.parseObject(json, getTClass()));
                }
                if (401 == httpException.code()) {
                    //登录过期 重新登录
                    logOut();
                }
            } else {
                onFailure(e, false);
            }
        } catch (Exception error) {
            error.printStackTrace();
            try {
                onFailure(error, false);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    @Override
    public void onComplete() {

    }

    protected abstract void onFailure(Throwable e, boolean isNetWorkError) throws Exception;

    protected abstract void onSuccess(T baseEntity) throws Exception;

    protected void onCodeError(T baseEntity) throws Exception {

    }

    /**
     * 退出登录
     */
    private void logOut() {
        try {
            new Thread(() -> EMClient.getInstance().logout(true)).start();
            Hawk.delete(SPKey.SP_KEY_USER_MY_INFO);
            Hawk.delete(SPKey.SP_KEY_USER_INFO);
            App.getInstance().exit();
            ARouter.getInstance().build(RouteTable.ROUTER_ACTIVITY_LOGIN).withBoolean("intentMain", false).navigation();
            ToastUtils.showShort("登录过期，请重新登录。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
